package engine

import (
	"fmt"
	"front/engine/conf"
	"net/http"
	"qingbing/xztools/chans"
	"qingbing/xztools/logs"
	"qingbing/xzutils/strs"
	"qingbing/xzutils/utils"
)

type Engine struct {
	Address string
	Port    string
	log     *logs.FileLog
}

/**
 * 扩展 http.ResponseWriter 实现
 *  记录请求信息，和返回的 body
 */
type EResponseWriter struct {
	http.ResponseWriter         // 响应
	*http.Request               // 请求
	Bytes               *[]byte // 输出结果
}

func (rw EResponseWriter) Write(b []byte) (int, error) {
	*rw.Bytes = append(*rw.Bytes, b...)
	return rw.ResponseWriter.Write(b)
}

// 新建引擎
func New(conf *conf.Conf) *Engine {
	e := &Engine{
		Address: conf.Address,
		Port:    conf.Port,
	}

	/**
	 * 日志格式化处理
	 */
	if conf.LogFormat == "" {

	} else {

	}
	logFormat := utils.IF(conf.LogFormat == "", "Engine: time - ip [method] [url] [request-post-form]\"agent\"", conf.LogFormat)
	conf.ConfFileLog.Formatter = func(data *chans.ChanData) string {
		if rw, ok := data.Data.(EResponseWriter); ok {
			replaces := map[string]any{
				"header":              rw.Request.Header,
				"request-body":        rw.Request.Body,
				"request-length":      rw.Request.ContentLength,
				"request-host":        rw.Request.Host,
				"request-form":        rw.Request.Form,
				"request-post-form":   rw.Request.PostForm,
				"request-remote-addr": rw.Request.RemoteAddr,
				"request-request-uri": rw.Request.RequestURI,
				"ip":                  utils.ClientIP(rw.Request),
				"time":                data.Time.Format("2006-01-02 15:04:05.0000"),
				"method":              rw.Request.Method,
				"url":                 rw.Request.URL.Path,
				"proto":               rw.Request.Proto,
				"agent":               rw.Request.UserAgent(),
				"body":                string(*rw.Bytes),
			}
			return strs.Replace(logFormat, replaces, false)
		}
		return fmt.Sprintf("[%s]: %s", data.Time.Format("2006-01-02 15:04:05.000000"), data.Data.(string))
	}
	e.log = logs.NewFileLog(&conf.ConfFileLog)
	return e
}

func (e Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	bs := make([]byte, 0)
	rw := EResponseWriter{
		ResponseWriter: w,
		Request:        r,
		Bytes:          &bs,
	}
	// 记录访问日志
	e.log.Append(rw)
}

// 启动web引擎
func (f *Engine) Run() {
	if err := http.ListenAndServe(fmt.Sprintf("%s:%s", f.Address, f.Port), f); err != nil {
		fmt.Println("Server start failed.")
	} else {
		fmt.Println("Server start success.")
	}
}
